import logging
log = logging.getLogger("statsdt")

# Default DataTable format
class BaseDTStats(object):
  def fill(self, dtParams, results, tags, datefmt, x, y):
    if 2 == len(dtParams[2]):
      self.fmt2cols(dtParams)
    return
  
  def fmt2cols(self, dtParams):
    cols = dtParams[0].popitem()
    _cols = cols[1].popitem()
    dtParams[0] = [cols[0], (_cols[0], _cols[1][0])]
    _rows = []
    for row in dtParams[1].iteritems():
      _rows.append([row[0], row[1].popitem()[1]])
    dtParams[1] = _rows
  
  # OBSOLETED,Not tested.
  def xyexchange(self, dtParams):
    assert(1 == dtParams[0].len())
    _cols = {} #non-first column
    _rows = {}
    firstCol = dtParams[0].popitem()[0]
    dtParams[0][(firstCol[0], "String", "")] = _cols
    for row in dtParams[1].iteritems():
      _cols[row[0]] = ("number", row[0])
      for col in row[1].iteritmes():
        if not col[0] in _rows:
          _rows[col[0]] = {}
        _rows[col[0]][row[0]] = col[1]
    dtParams[1] = _rows
    dtParams[2].append(firstCol)
    dtParams[2] = dtParams[2]+sorted(_cols.keys())

# X is date
class DTX(BaseDTStats):
  def fill(self, dtParams, results, tags, datefmt, x, y):
    _cols = {} #non-first column
    firstCol = "Date"
    dtParams[0][(firstCol, "String", "")] = _cols
    dfmts = {} #temp data format row dict
    for rec in results:
      colName = " ".join(rec.tags) + "(" + rec.unit + ")"
      _cols[colName] = ("number", colName)
      tmpfmt = datefmt
      if 0 == len(datefmt):
        tmpfmt = str(rec.dfmt)
      rowName = self.getDateRowName(dtParams, dfmts, colName, rec.date, tmpfmt)
      if not rowName in dtParams[1]:
        dtParams[1][rowName] = {}
      if colName in dtParams[1][rowName]:
        log.warn("V1[%s,%s,%.1f] and V2[%s,%s,%.1f] conflict!",
                 rowName, colName, dtParams[1][rowName][colName],
                 rec.date.strftime("%Y%m%d%H%M%S"), rec.tags, rec.value)
      dtParams[1][rowName][colName] = rec.value
    dtParams[2].append(firstCol)
    dtParams[2] = dtParams[2]+sorted(_cols.keys())
    BaseDTStats.fill(self, dtParams, results, tags, datefmt, x, y)
  
  # If a date has same output with another under the date format,
  # the TWO date will all use the "%Y%m%d%H%M%S" format.
  def getDateRowName(self, dtParams, dfmts, colName, recdate, datefmt):
    rowName = recdate.strftime( datefmt )
    if "%Y%m%d%H%M%S" != datefmt:
      if not rowName in dfmts or not rowName in dtParams[1] or not colName in dtParams[1][rowName]:
        dfmts[rowName] = recdate.strftime("%Y%m%d%H%M%S")
        return rowName
      assert(rowName in dtParams[1])
      dtParams[1][dfmts.pop(rowName)] = dtParams[1].pop(rowName)
      rowName = recdate.strftime("%Y%m%d%H%M%S")
    return rowName

# Y is date
class DTY(BaseDTStats):
  def fill(self, dtParams, results, tags, datefmt, x, y):
    _cols = {} #non-first column
    firstCol = " ".join(tags)
    dtParams[0][(firstCol, "String", "")] = _cols
    for rec in results:
      colName = rec.date.strftime("%Y%m%d%H%M%S")
      tmpfmt = datefmt
      if 0 == len(datefmt):
        tmpfmt = str(rec.dfmt)
      _cols[colName] = ("number", rec.date.strftime(tmpfmt))
      rowName = " ".join(rec.tags) + "(" + rec.unit + ")"
      if not rowName in dtParams[1]:
        dtParams[1][rowName] = {}
      if colName in dtParams[1][rowName]:
        log.warn("V1[%s,%s,%.1f] and V2[%s,%s,%.1f] conflict!",
                 rowName, colName, dtParams[1][rowName][colName],
                 rec.date.strftime("%Y%m%d%H%M%S"), rec.tags, rec.value)
      dtParams[1][rowName][colName] = rec.value
    dtParams[2].append(firstCol)
    dtParams[2] = dtParams[2]+sorted(_cols.keys())
    BaseDTStats.fill(self, dtParams, results, tags, datefmt, x, y)
    
# X and Y are tags, and date is still in Y by default
#class TagsDT(BaseDTStats):
#  def fill(self, dtParams, results, tags, datefmt, x, y):
#    _cols = {} #non-first column
#    firstCol = " ".join(tags) # Whatever is ok.
#    dtParams[0][(firstCol, "String", "")] = _cols
#    for rec in results:
#      yTags = set(rec.tags) - set(tags) - set(y)
#      colName = " ".join(yTags) + rec.date.strftime("%Y%m%d%H%M%S")
#      _cols[colName] = ("number", colName)
#      rowName = " ".join(set(rec.tags) - set(tags) - set(x))
#      if not rowName in dtParams[1]:
#        dtParams[1][rowName] = {}
#      dtParams[1][rowName][colName] = rec.value
#    dtParams[2].append(firstCol)
#    dtParams[2] = dtParams[2]+sorted(_cols.keys())
#    BaseDTStats.fill(self, dtParams, results, tags, datefmt, x, y)
#    

class DTTags(BaseDTStats):
  def fill(self, dtParams, results, tags, datefmt, x, y):
    _cols = {} #non-first column
    firstCol = " ".join(tags) # Whatever is ok.
    dtParams[0][(firstCol, "String", "")] = _cols
    for rec in results:
      yTags = set(rec.tags) - (set(rec.tags) - set(y))
      if 0 == len("".join(yTags)):
        yTags = set(rec.tags) - set(x)
      colName = " ".join(yTags) + "(" + rec.date.strftime("%Y%m%d%H%M%S") + ")"
      tmpfmt = datefmt
      if 0 == len(datefmt):
        tmpfmt = str(rec.dfmt)
      _cols[colName] = ("number", " ".join(yTags) + "(" + rec.date.strftime(tmpfmt) + ")")
      
      rowName = " ".join(set(rec.tags) - (set(rec.tags) - set(x)))
      if 0 == len("".join(rowName)):
        rowName = " ".join(set(rec.tags) - set(y))
      if not rowName in dtParams[1]:
        dtParams[1][rowName] = {}
      if colName in dtParams[1][rowName]:
        log.warn("V1[%s,%s,%.1f] and V2[%s,%s,%.1f] conflict!",
                 rowName, colName, dtParams[1][rowName][colName],
                 rec.date.strftime("%Y%m%d%H%M%S"), rec.tags, rec.value)
      dtParams[1][rowName][colName] = rec.value
    dtParams[2].append(firstCol)
    dtParams[2] = dtParams[2]+sorted(_cols.keys())
    BaseDTStats.fill(self, dtParams, results, tags, datefmt, x, y)
    